package com.bosssoft.ct.springcloud.utils.token;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

/**
 * token生成与解析工具
 *
 * @author ChenTong
 * @version 1.0
 * @date 2020/6/23 21:31
 * @copyright
 * @modified
 * @see
 * @since
 **/
public class TokenUtil {
    private TokenUtil(){}
    // 签名密钥
    public static final String SECRET = "admin";
    // token默认有效事件10小时
    public static final Long TTL_MILLIS = 36000000L;
    /**
     * 更具username 生成token 具有默认时间
     * @param username
     * @return token
     */
    public static String createJwtToken(String username){
        return createJwtToken(username, TTL_MILLIS);
    }

    /**
     * 生成token
     * @param username 用户名
     * @param ttlMillis 签发时间（有效时间，过期会报错）
     * @return token string
     */
    public static String createJwtToken(String username, long ttlMillis){
        // 签名算法，将token进行签名
        SignatureAlgorithm signatureAlgorithm=SignatureAlgorithm.HS256;
        // 生成签发时间
        long nowMills= System.currentTimeMillis();
        Date now=new Date(nowMills);
        // 通过秘钥签名JWT
        byte[] apiKeySecretBytes= DatatypeConverter.parseBase64Binary(SECRET);
        Key signingKey=new SecretKeySpec(apiKeySecretBytes,signatureAlgorithm.getJcaName());
        // 创建token
        JwtBuilder builder= Jwts.builder().setId(username)
                .setIssuedAt(now)
                .signWith(signatureAlgorithm,signingKey);
        // 添加过期时间
        if(ttlMillis>=0){
            long expMillis=nowMills+ttlMillis;
            Date exp=new Date(expMillis);
            builder.setExpiration(exp);
        }
        return builder.compact();
    }

    /**
     * @description 解析token 验证和读取JWT的示例方法
     * @author ChenTong
     * @param jwt
     * @return io.jsonwebtoken.Claims
     * @date 2020/6/15 11:05
     */
    public static Claims parseJWT(String jwt){
        return Jwts.parser()
                .setSigningKey(DatatypeConverter.parseBase64Binary(SECRET))
                .parseClaimsJws(jwt).getBody();
    }
}
